﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;

namespace Mytrip.Users
{
    public class RoleRepository : RoleProvider
    {
        usersEntities _db = new usersEntities(UsersSetting.connectionString);
        //IRepository db = new IRepository(RepositorySetting.connectionString);
        public override void AddUsersToRoles(string[] usernames, string[] roleNames)
        {
            foreach (string username in usernames)
            {
                foreach (string roleName in roleNames)
                {
                    var user = _GetUser(username);
                    if (user != null)
                    {
                        if (_GetRole(roleName) == null)
                            _CreateRole(roleName);
                        bool addRole = true;
                        var role = _GetRole(roleName);
                        foreach (mytrip_Roles x in user.mytrip_Roles)
                        {
                            if (roleName == x.RoleName)
                                addRole = false;
                        }
                        if (addRole)
                        {
                            mytrip_Users x = user;
                            x.mytrip_Roles.Add(role);
                            _db.SaveChanges();
                        }
                    }
                }
            }
        }
        public override string ApplicationName
        {
            get
            {
                return UsersSetting.applicationName;
            }
            set { UsersSetting.applicationName = value; }
        }
        public override void CreateRole(string roleName)
        {
            _CreateRole(roleName);
        }
        public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
        {
            bool result = false;
            var role = _GetRole(roleName);
            if (role != null)
            {
                _RemoveRoleFromUsers(roleName);
                mytrip_Roles x = role;
                _db.DeleteObject(x);
                _db.SaveChanges();
                result = true;
            }
            return result;
        }
        public override string[] FindUsersInRole(string roleName, string usernameToMatch)
        {
            string[] result = new string[0];
            var role = _GetRole(roleName);
            if (role != null)
            {
                int namberUser = 0;
                int countUser = role.mytrip_Users.Count();
                result = new string[countUser];
                foreach (mytrip_Users x in role.mytrip_Users)
                {
                    if (x.UserName.IndexOf(usernameToMatch) != -1)
                    {
                        result[namberUser] = x.UserName;
                        namberUser++;
                    }
                }
            }
            return result;
        }
        public override string[] GetAllRoles()
        {
            string[] result = new string[0];
            var roles = _db.mytrip_Roles.OrderBy(x => x.RoleName);
            if (roles != null)
            {
                int namberRole = 0;
                int countRoles = roles.Count();
                result = new string[countRoles];
                foreach (mytrip_Roles x in roles)
                {
                    result[namberRole] = x.RoleName;
                    namberRole++;
                }
            }
            return result;
        }
        public override string[] GetRolesForUser(string username)
        {
            string[] result = new string[0];
            var user = _GetUser(username);
            if (user != null)
            {
                int namberRole = 0;
                int countRoles = user.mytrip_Roles.Count();
                result = new string[countRoles];
                foreach (mytrip_Roles x in user.mytrip_Roles)
                {
                    result[namberRole] = x.RoleName;
                    namberRole++;
                }
            }
            return result;
        }
        public override string[] GetUsersInRole(string roleName)
        {
            string[] result = new string[0];
            var role = _GetRole(roleName);
            if (role != null)
            {
                int namberUser = 0;
                int countUser = role.mytrip_Users.Count();
                result = new string[countUser];
                foreach (mytrip_Users x in role.mytrip_Users)
                {
                    result[namberUser] = x.UserName;
                    namberUser++;
                }
            }
            return result;
        }
        public override bool IsUserInRole(string username, string roleName)
        {
            bool result = false;
            var role = _GetRole(roleName);
            if (role != null)
            {
                foreach (mytrip_Users x in role.mytrip_Users)
                {
                    if (x.UserName == username)
                        result = true;
                }
            }
            return result;
        }
        public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
        {
            foreach (string username in usernames)
            {
                foreach (string roleName in roleNames)
                {
                    var user = _GetUser(username);
                    var role = _GetRole(roleName);
                    if (user != null && role != null)
                    {
                        bool removeRole = true;
                        foreach (mytrip_Roles x in user.mytrip_Roles)
                        {
                            if (roleName != x.RoleName)
                                removeRole = false;
                        }
                        if (removeRole)
                        {
                            mytrip_Users x = user;
                            x.mytrip_Roles.Remove(role);
                            _db.SaveChanges();
                        }
                    }
                }
            }
        }
        public override bool RoleExists(string roleName)
        {
            if (_GetRole(roleName) != null)
                return true;
            else
                return false;
        }
        /*-----------------------------------------------------------------*/
        #region создать уникальный RoleId
        private int _RoleId()
        {
            int result;
            int roleId;
            for (roleId = 1; _GetRoleId(roleId) != null; roleId++) ;
            result = roleId;
            return result;
        }
        #endregion
        #region получить пользователя по имени
        private mytrip_Users _GetUser(string username)
        {
            return _db.mytrip_Users.FirstOrDefault(x => x.UserName == username);
        }
        #endregion
        #region получить роль по Id
        private mytrip_Roles _GetRoleId(int roleid)
        {
            return _db.mytrip_Roles.FirstOrDefault(x => x.RoleId == roleid);
        }
        #endregion
        #region удалить пользователей из роли
        private void _RemoveRoleFromUsers(string rolename)
        {
            var role = _GetRole(rolename);
            if (role.mytrip_Users != null)
            {
                foreach (mytrip_Users x in role.mytrip_Users.ToList())
                {
                    var user = _GetUser(x.UserName);
                    role.mytrip_Users.Remove(user);
                    _db.SaveChanges();
                }
            }
        }
        #endregion
        #region создать роль
        private void _CreateRole(string roleName)
        {
            var role = _GetRole(roleName);
            if (role == null)
            {
                mytrip_Roles x = new mytrip_Roles
                {
                    RoleId = _RoleId(),
                    RoleName = roleName
                };
                _db.AddTomytrip_Roles(x);
                _db.SaveChanges();
            }
        }
        #endregion
        #region получить роль по имени
        public mytrip_Roles _GetRole(string rolename)
        {
            return _db.mytrip_Roles.FirstOrDefault(x => x.RoleName == rolename);
        }
        #endregion
        #region удалить пользователя из роли
        private void _RemoveRoleFromUser(string username, string rolename)
        {
            var role = _GetRole(rolename);
                foreach (mytrip_Users x in role.mytrip_Users.ToList())
                {
                    if (username == x.UserName)
                    {
                        var user = _GetUser(x.UserName);
                        role.mytrip_Users.Remove(user);
                        _db.SaveChanges();
                    }
               
            }
        }
        #endregion
        #region добавить пользователя в роль
        public void _AddRoleFromUser(string username, string rolename)
        {
            var role = _GetRole(rolename);
            var user = _GetUser(username);            
            role.mytrip_Users.Add(user);
            _db.SaveChanges();
             
        }
        #endregion
        #region получить все роли
        public IQueryable<mytrip_Roles> _GetAllRoles(int pageIndex, int pageSize, string sort, out int total)
        {
            total = _db.mytrip_Roles.OrderBy(x => x.RoleName).Count();
            var roles = _db.mytrip_Roles.OrderBy(x => x.RoleName).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            if (sort == "RoleName")
                roles = _db.mytrip_Roles.OrderBy(x => x.RoleName).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            if (sort == "_RoleName")
                roles = _db.mytrip_Roles.OrderByDescending(x => x.RoleName).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            if (sort == "UserCount")
                roles = _db.mytrip_Roles.OrderBy(x => x.mytrip_Users.Count()).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            if (sort == "_UserCount")
                roles = _db.mytrip_Roles.OrderByDescending(x => x.mytrip_Users.Count()).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            if (!String.IsNullOrEmpty(sort) && sort != "RoleName" && sort != "_RoleName" && sort != "UserCount" && sort != "_UserCount")
            {
                total = _db.mytrip_Roles.Where(x => x.RoleName.IndexOf(sort) != -1).Count();
                roles = _db.mytrip_Roles.Where(x => x.RoleName.IndexOf(sort) != -1).OrderBy(x => x.RoleName).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            }
            return roles;
        }
        public IQueryable<mytrip_Roles> _GetAllRoles()
        {
            return _db.mytrip_Roles.OrderBy(x => x.RoleName);
        }
        #endregion
        #region добавить удалить пользователя в роли
        public void _UnlockUserInRole(string username, string roleName)
        {
            bool result = false;
            var role = _GetRole(roleName);
            if (role != null)
            {
                foreach (mytrip_Users x in role.mytrip_Users)
                {
                    if (x.UserName == username)
                        result = true;
                }
            }
            if (result) {
            _RemoveRoleFromUser(username, roleName);
            }
            else { _AddRoleFromUser(username, roleName); }
        }
        #endregion
        public string _GetSearchRoles(string search)
        {
            var roles= _db.mytrip_Roles.Where(x => x.RoleName.IndexOf(search)!=-1);
            StringBuilder result = new StringBuilder();
            foreach (mytrip_Roles item in roles)
            {
                result.AppendLine(item.RoleName);
            }
            return result.ToString();
        }
    }
}